#include <my_head.h>

#define MY_PAGE_SIZE 4*1024

int main(int argc, const char *argv[]){
    // 获取键值
    key_t my_key = ftok("/home/linux", 'A');
    if(-1 == my_key)
        ERR_LOG("ftok error");
    // 创建或者获取共享内存
    int shmid = shmget(my_key, 2*MY_PAGE_SIZE, IPC_CREAT|0666);
    if(-1 == shmid)
        ERR_LOG("shmget error");
    // 映射共享内存当当前进程中
    char *p = shmat(shmid, NULL, 0);
    if((void *)-1 == p)
        ERR_LOG("shmat error");

    // 创建或者获取信号灯集
    int semid = 0;
    if(-1 == (semid = semget(my_key, 2, IPC_CREAT|0666)))
        ERR_LOG("semget error");
    // 初始化信号灯集 // 初始化的操作只能做一次 如果已经开始使用信号灯集了 重复初始化会导致问题
    // semctl(semid, 0, SETVAL, 1);
    // semctl(semid, 1, SETVAL, 0);

    // 使用共享内存
    // 将共享内存的内容打印到终端
    struct sembuf my_op; // 用来做PV操作的结构体
    while(1){
        // 获取1号灯的资源
        my_op.sem_num = 1;
        my_op.sem_op = -1;
        my_op.sem_flg = 0;
        semop(semid, &my_op, 1);

        printf("共享内存中的内容是:[%s]\n", p);

        // 释放0号灯的资源
        my_op.sem_num = 0;
        my_op.sem_op = 1;
        my_op.sem_flg = 0;
        semop(semid, &my_op, 1);

        if(!strcmp(p, "quit")){
            break;
        }
    }
    // 取消映射
    if(-1 == shmdt(p))
        ERR_LOG("shmdt error");
    // 标记销毁 --只有当最后一个进程将该共享内存取消映射时 才会被销毁
    if(-1 == shmctl(shmid, IPC_RMID, NULL))
        ERR_LOG("shmctl error");
    // 删除信号灯集
    if(-1 == semctl(semid, 0, IPC_RMID))
    ERR_LOG("semid");

    return 0;
}